class AudioService {
  constructor() {
    // 音频流
    this.audioStream = null
    
    // MediaRecorder实例
    this.mediaRecorder = null
    
    // 音频数据块数组
    this.audioChunks = []
    
    // 录音状态
    this.isRecording = false
    
    // 麦克风启用状态
    this.isMicEnabled = false
    
    // 静默超时定时器
    this.silenceTimeout = null
    
    // 音频上下文
    this.audioContext = null
    
    // 音频分析器
    this.analyser = null
    
    // 声音检测间隔定时器
    this.soundDetectionInterval = null
    
    // 配置参数
    this.config = {
      // 声音阈值（0-1范围）
      soundThreshold: 0.05,
      
      // 静默超时时间（毫秒）
      silenceTimeoutMs: 1500,
      
      // 声音检测间隔（毫秒）
      detectionIntervalMs: 100,
      
      // 音频格式
      audioMimeType: 'audio/webm',
      
      // 录音数据块大小（毫秒）
      bufferSizeMs: 100
    }
    
    // 回调函数
    this.callbacks = {
      // 录音开始回调
      onRecordingStart: null,
      
      // 录音停止回调
      onRecordingStop: null,
      
      // 录音数据可用回调
      onDataAvailable: null,
      
      // 音频分析回调
      onAudioAnalysed: null,
      
      // 错误回调
      onError: null
    }
  }
  
  // 设置回调函数
  setCallback(type, callback) {
    if (this.callbacks.hasOwnProperty(type)) {
      this.callbacks[type] = callback
    } else {
      console.warn(`未知的回调类型: ${type}`)
    }
  }
  
  // 请求麦克风权限
  async requestMicrophonePermission() {
    try {
      // 请求用户媒体权限
      await navigator.mediaDevices.getUserMedia({ audio: true })
      console.log('麦克风权限已获取')
      return true
    } catch (error) {
      console.error('获取麦克风权限失败:', error)
      
      // 调用错误回调
      if (this.callbacks.onError) {
        this.callbacks.onError('获取麦克风权限失败: ' + error.message)
      }
      
      return false
    }
  }
  
  // 启用麦克风
  async enableMicrophone() {
    try {
      // 检查是否已经启用
      if (this.isMicEnabled) {
        console.warn('麦克风已经是启用状态')
        return
      }
      
      // 获取音频流
      this.audioStream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true
        }
      })
      
      this.isMicEnabled = true
      console.log('麦克风已启用')
      
      // 设置音频分析
      this.setupAudioAnalysis()
      
    } catch (error) {
      console.error('启用麦克风失败:', error)
      
      // 调用错误回调
      if (this.callbacks.onError) {
        this.callbacks.onError('启用麦克风失败: ' + error.message)
      }
      
      throw error
    }
  }
  
  // 禁用麦克风
  disableMicrophone() {
    // 停止录音
    if (this.isRecording) {
      this.stopRecording()
    }
    
    // 停止音频流
    if (this.audioStream) {
      this.audioStream.getTracks().forEach(track => track.stop())
      this.audioStream = null
    }
    
    // 清理音频上下文
    if (this.audioContext) {
      this.audioContext.close()
      this.audioContext = null
      this.analyser = null
    }
    
    // 清除声音检测间隔
    if (this.soundDetectionInterval) {
      clearInterval(this.soundDetectionInterval)
      this.soundDetectionInterval = null
    }
    
    // 清除静默超时
    if (this.silenceTimeout) {
      clearTimeout(this.silenceTimeout)
      this.silenceTimeout = null
    }
    
    this.isMicEnabled = false
    console.log('麦克风已禁用')
  }
  
  // 设置音频分析
  setupAudioAnalysis() {
    try {
      // 创建音频上下文
      this.audioContext = new (window.AudioContext || window.webkitAudioContext)()
      
      // 创建音频源
      const source = this.audioContext.createMediaStreamSource(this.audioStream)
      
      // 创建分析器
      this.analyser = this.audioContext.createAnalyser()
      this.analyser.fftSize = 256
      
      // 连接音频源到分析器
      source.connect(this.analyser)
      
      // 开始声音检测
      this.startSoundDetection()
      
    } catch (error) {
      console.error('设置音频分析失败:', error)
      
      // 调用错误回调
      if (this.callbacks.onError) {
        this.callbacks.onError('设置音频分析失败: ' + error.message)
      }
    }
  }
  
  // 开始声音检测
  startSoundDetection() {
    if (!this.analyser) {
      console.error('音频分析器未初始化，无法开始声音检测')
      return
    }
    
    const bufferLength = this.analyser.frequencyBinCount
    const dataArray = new Uint8Array(bufferLength)
    
    // 每指定间隔检查一次声音级别
    this.soundDetectionInterval = setInterval(() => {
      if (!this.isMicEnabled || !this.analyser) {
        return
      }
      
      // 获取频域数据
      this.analyser.getByteFrequencyData(dataArray)
      
      // 计算平均音量
      let sum = 0
      for (let i = 0; i < bufferLength; i++) {
        sum += dataArray[i]
      }
      
      const average = sum / bufferLength
      const normalizedAverage = average / 255 // 归一化到0-1范围
      
      // 调用音频分析回调
      if (this.callbacks.onAudioAnalysed) {
        this.callbacks.onAudioAnalysed({
          volume: normalizedAverage,
          isSoundDetected: normalizedAverage > this.config.soundThreshold
        })
      }
      
      // 检测到声音且当前未录音，则开始录音
      if (normalizedAverage > this.config.soundThreshold && !this.isRecording) {
        this.startRecording()
      }
      
      // 正在录音但声音低于阈值，更新静默超时
      if (this.isRecording && normalizedAverage <= this.config.soundThreshold) {
        this.updateSilenceTimeout()
      }
      
    }, this.config.detectionIntervalMs)
  }
  
  // 更新静默超时
  updateSilenceTimeout() {
    // 清除之前的超时
    if (this.silenceTimeout) {
      clearTimeout(this.silenceTimeout)
    }
    
    // 设置新的超时
    this.silenceTimeout = setTimeout(() => {
      if (this.isRecording) {
        this.stopRecording()
      }
    }, this.config.silenceTimeoutMs)
  }
  
  // 开始录音
  startRecording() {
    try {
      // 检查麦克风是否启用
      if (!this.isMicEnabled || !this.audioStream) {
        throw new Error('麦克风未启用，无法开始录音')
      }
      
      // 检查是否已经在录音
      if (this.isRecording) {
        console.warn('已经在录音中，无需重复开始')
        return
      }
      
      // 重置音频块数组
      this.audioChunks = []
      
      // 创建MediaRecorder实例
      this.mediaRecorder = new MediaRecorder(this.audioStream, {
        mimeType: this.config.audioMimeType
      })
      
      // 设置数据可用事件
      this.mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          this.audioChunks.push(event.data)
          
          // 调用数据可用回调
          if (this.callbacks.onDataAvailable) {
            this.callbacks.onDataAvailable(event.data)
          }
        }
      }
      
      // 设置录音停止事件
      this.mediaRecorder.onstop = () => {
        this.handleRecordingStopped()
      }
      
      // 设置录音错误事件
      this.mediaRecorder.onerror = (error) => {
        console.error('录音出错:', error)
        
        // 调用错误回调
        if (this.callbacks.onError) {
          this.callbacks.onError('录音出错: ' + error.message)
        }
        
        this.isRecording = false
      }
      
      // 开始录音
      this.mediaRecorder.start(this.config.bufferSizeMs)
      this.isRecording = true
      
      console.log('开始录音...')
      
      // 调用录音开始回调
      if (this.callbacks.onRecordingStart) {
        this.callbacks.onRecordingStart()
      }
      
    } catch (error) {
      console.error('开始录音失败:', error)
      
      // 调用错误回调
      if (this.callbacks.onError) {
        this.callbacks.onError('开始录音失败: ' + error.message)
      }
    }
  }
  
  // 停止录音
  stopRecording() {
    if (!this.isRecording || !this.mediaRecorder) {
      console.warn('当前没有在录音，无需停止')
      return
    }
    
    // 清除静默超时
    if (this.silenceTimeout) {
      clearTimeout(this.silenceTimeout)
      this.silenceTimeout = null
    }
    
    // 停止录音
    this.mediaRecorder.stop()
    this.isRecording = false
    
    console.log('停止录音...')
  }
  
  // 处理录音停止
  handleRecordingStopped() {
    console.log('录音已停止')
    
    // 调用录音停止回调
    if (this.callbacks.onRecordingStop) {
      // 如果有录音数据，创建音频Blob并传递给回调
      if (this.audioChunks.length > 0) {
        const audioBlob = new Blob(this.audioChunks, {
          type: this.config.audioMimeType
        })
        
        this.callbacks.onRecordingStop(audioBlob)
        
        // 清空音频块数组
        this.audioChunks = []
      } else {
        // 没有录音数据
        this.callbacks.onRecordingStop(null)
      }
    }
  }
  
  // 立即获取当前录音数据
  getCurrentAudioData() {
    if (this.audioChunks.length === 0) {
      return null
    }
    
    return new Blob(this.audioChunks, {
      type: this.config.audioMimeType
    })
  }
  
  // 转换音频格式（WebM转WAV）
  async convertToWav(webmBlob) {
    try {
      // 注意：完整的WebM到WAV的转换需要更复杂的音频处理库
      // 这里只是简单地创建一个WAV类型的Blob
      // 实际项目中可能需要使用如ffmpeg.js等库进行格式转换
      
      // 读取WebM数据
      const arrayBuffer = await this.readBlobAsArrayBuffer(webmBlob)
      
      // 这里应该进行音频格式转换
      // 为了简化示例，我们直接返回带有WAV类型的Blob
      // 实际项目中应该使用专门的音频处理库
      
      return new Blob([arrayBuffer], { type: 'audio/wav' })
    } catch (error) {
      console.error('转换音频格式失败:', error)
      
      // 调用错误回调
      if (this.callbacks.onError) {
        this.callbacks.onError('转换音频格式失败: ' + error.message)
      }
      
      throw error
    }
  }
  
  // 将Blob读取为ArrayBuffer
  readBlobAsArrayBuffer(blob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.onerror = reject
      reader.readAsArrayBuffer(blob)
    })
  }
  
  // 设置配置参数
  setConfig(newConfig) {
    this.config = { ...this.config, ...newConfig }
    console.log('音频服务配置已更新:', this.config)
  }
  
  // 获取当前状态
  getStatus() {
    return {
      isMicEnabled: this.isMicEnabled,
      isRecording: this.isRecording,
      hasAudioStream: !!this.audioStream,
      hasAudioContext: !!this.audioContext,
      audioChunksCount: this.audioChunks.length
    }
  }
  
  // 清理资源
  cleanup() {
    console.log('清理音频服务资源')
    
    // 禁用麦克风
    this.disableMicrophone()
    
    // 重置回调
    this.callbacks = {
      onRecordingStart: null,
      onRecordingStop: null,
      onDataAvailable: null,
      onAudioAnalysed: null,
      onError: null
    }
  }
}

// 创建单例实例
export default new AudioService()